using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using ALib;
using AxTWSLib;
using TradingPlatform.IB.Operations;
using TWSLib;
using _DTwsEvents_historicalDataEventHandler = AxTWSLib._DTwsEvents_historicalDataEventHandler;

namespace TradingPlatform.IB.Operations
{
    public class ContractDetails
    {
        private readonly AxTws _tws;

        private readonly TickerNameAndId _tickerId;

        public SortedList<string, SortedList<ContractDetailsItemType, string>> _result;

        public ContractDetails(AxTws tws)
        {
            _tws = tws;
            _tws.contractDetailsEx += new AxTWSLib._DTwsEvents_contractDetailsExEventHandler(_tws_contractDetailsEx);
            _tickerId = new TickerNameAndId();
            _result = new SortedList<string, SortedList<ContractDetailsItemType, string>>();
        }

        public void RequestContractDetails(string exchange, string secType, string symbol, string expiry, string currency)
        {
            IContract contract = _tws.createContract();

            contract.exchange = exchange;
            contract.secType = secType;
            contract.symbol = symbol;
            contract.expiry = expiry;
            contract.currency = currency;

            string tickerName = TickerNameAndId.ToTickerName(exchange, secType, symbol, expiry, currency);
            _tickerId.Add(tickerName);
            int tickerId = _tickerId.GetId(tickerName);

            if (!_result.ContainsKey(tickerName))
            {
                _result.Add(tickerName, new SortedList<ContractDetailsItemType, string>());
            }
            _result[tickerName].Clear();

            _tws.reqContractDetailsEx(tickerId, contract);
        }

        void _tws_contractDetailsEx(object sender, _DTwsEvents_contractDetailsExEvent e)
        {
            int tickerId = e.reqId;
            string tickerName = _tickerId.GetTickerName(tickerId);

            _result[tickerName].Add(ContractDetailsItemType.bondType, e.contractDetails.bondType);
            _result[tickerName].Add(ContractDetailsItemType.callable, e.contractDetails.callable.ToString());
            _result[tickerName].Add(ContractDetailsItemType.category, e.contractDetails.category);
            _result[tickerName].Add(ContractDetailsItemType.contractMonth, e.contractDetails.contractMonth);
            _result[tickerName].Add(ContractDetailsItemType.convertible, e.contractDetails.convertible.ToString());
            _result[tickerName].Add(ContractDetailsItemType.coupon, e.contractDetails.coupon.ToString());
            _result[tickerName].Add(ContractDetailsItemType.couponType, e.contractDetails.couponType);
            _result[tickerName].Add(ContractDetailsItemType.cusip, e.contractDetails.cusip);
            _result[tickerName].Add(ContractDetailsItemType.descAppend, e.contractDetails.descAppend);
            _result[tickerName].Add(ContractDetailsItemType.industry, e.contractDetails.industry);
            _result[tickerName].Add(ContractDetailsItemType.issueDate, e.contractDetails.issueDate);
            _result[tickerName].Add(ContractDetailsItemType.liquidHours, e.contractDetails.liquidHours);
            _result[tickerName].Add(ContractDetailsItemType.longName, e.contractDetails.longName);
            _result[tickerName].Add(ContractDetailsItemType.marketName, e.contractDetails.marketName);
            _result[tickerName].Add(ContractDetailsItemType.maturity, e.contractDetails.maturity);
            _result[tickerName].Add(ContractDetailsItemType.minTick, e.contractDetails.minTick.ToString());
            _result[tickerName].Add(ContractDetailsItemType.nextOptionDate, e.contractDetails.nextOptionDate);
            _result[tickerName].Add(ContractDetailsItemType.nextOptionPartial, e.contractDetails.nextOptionPartial.ToString());
            _result[tickerName].Add(ContractDetailsItemType.nextOptionType, e.contractDetails.nextOptionType);
            _result[tickerName].Add(ContractDetailsItemType.notes, e.contractDetails.notes);
            _result[tickerName].Add(ContractDetailsItemType.orderTypes, e.contractDetails.orderTypes);
            _result[tickerName].Add(ContractDetailsItemType.priceMagnifier, e.contractDetails.priceMagnifier.ToString());
            _result[tickerName].Add(ContractDetailsItemType.putable, e.contractDetails.putable.ToString());
            _result[tickerName].Add(ContractDetailsItemType.ratings, e.contractDetails.ratings);
            _result[tickerName].Add(ContractDetailsItemType.subcategory, e.contractDetails.subcategory);
            _result[tickerName].Add(ContractDetailsItemType.timeZoneId, e.contractDetails.timeZoneId);
            _result[tickerName].Add(ContractDetailsItemType.tradingClass, e.contractDetails.tradingClass);
            _result[tickerName].Add(ContractDetailsItemType.tradingHours, e.contractDetails.tradingHours);
            _result[tickerName].Add(ContractDetailsItemType.underConId, e.contractDetails.underConId.ToString());
            _result[tickerName].Add(ContractDetailsItemType.validExchanges, e.contractDetails.validExchanges);
        }
    }
}